package com.heima.wemedia.scan.service.Impl;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.heima.aliyun.AliyunGreenTemplate;
import com.heima.file.MinIOTemplate;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.scan.dao.WmNewsDao;
import com.heima.wemedia.scan.dao.WmSensitiveDao;
import com.heima.wemedia.scan.service.WmNewsAutoScanService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {
    @Resource
    private WmNewsDao wmNewsDao;

    @Resource
    private MinIOTemplate minIOTemplate;

    @Resource
    private AliyunGreenTemplate aliyunGreenTemplate;

    @Resource
    private WmSensitiveDao wmSensitiveDao;

    @Override
    public void autoScanNews(Long newsId) {
        //判断id是否为空
        if (newsId == null) {
            throw new RuntimeException("传入参数为空");
        }
        //根据id查询文章信息
        WmNews wmNews = wmNewsDao.queryById(newsId);
        //判断查询数据是否存在
        if (wmNews == null) {
            throw new RuntimeException("查询数据不存在");
        }
        //查看文章状态
        if (wmNews.getStatus() != 1) {
            return;
        }
        //抽取文章信息
        Map<String, Object> textAndImages = extractTextAndImages(wmNews);
        //进行文本审核
        String text = (String) textAndImages.get("text");
        //敏感词检测
        boolean sensitiveScan=handleSensitiveScan(wmNews,text);
        boolean textScan = handleTextScan(wmNews, text);
        if (!textScan) {
            return;
        }
        //进行内容审核
        List<String> images = (List<String>) textAndImages.get("images");
        boolean imagesScan = handleImageScan(wmNews, images);
        if (!imagesScan) {
            return;
        }
        updateStatus(wmNews, 8, "审核通过");
    }
    /*敏感词检测*/
    private boolean handleSensitiveScan(WmNews wmNews, String text) {
        if (StringUtils.isEmpty(text)) {
            return true;
        }

        //进行敏感词匹配
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(text);
        if (MapUtil.isEmpty(stringIntegerMap)){
            return true;
        }
        updateStatus(wmNews,2,"文本或图片内容中包含敏感词");
        return false;
    }


    /*图片审核*/
    private boolean handleImageScan(WmNews wmNews, List<String> images) {
        //判断图片是否为空
        if (CollectionUtils.isEmpty(images)) {
            return true;
        }
        //去重提高效率
        List<String> collect = images.stream().distinct().collect(Collectors.toList());
        //TODO项目上线之前需要将图片审核的方式修改为根据URL审核
        List<byte[]> bytes = collect.stream().map(url -> minIOTemplate.downLoadFile(url)).collect(Collectors.toList());
        // 阿里云审核
        Map<String, String> stringStringMap = aliyunGreenTemplate.greenImageScan(bytes);
        //审核成功
        if ("pass".equals(stringStringMap.get("suggestion"))) {
            return true;
        }
        //审核失败
        if ("block".equals(stringStringMap.get("suggestion"))) {
            updateStatus(wmNews, 2, "图片中包含违规内容, 请修改后发布!");
            return false;
        }
        //需要转人工
        if ("review".equals(stringStringMap.get("suggestion"))) {
            updateStatus(wmNews, 3, "图片中包含不确定因素, 请等待进一步审核 !");
            return false;
        }
        return false;
    }

    /*文本审核*/
    private boolean handleTextScan(WmNews wmNews, String text) {
        //校验参数是否为空
        if (StringUtils.isBlank(text)) {
            return true;
        }
        //审核完毕之后会返回3种情况, pass : 审核通过  block审核失败  review :需要人工审核
        Map<String, String> stringStringMap = aliyunGreenTemplate.greenTextScan(text);
        //审核成功
        if ("pass".equals(stringStringMap.get("suggestion"))) {
            return true;
        }
        //审核失败
        if ("block".equals(stringStringMap.get("suggestion"))) {
            updateStatus(wmNews, 2, "文章内容中包含违规内容，请修改后发布");
            return false;
        }
        //需要转人工
        if ("review".equals(stringStringMap.get("suggestion"))) {
            updateStatus(wmNews, 3, "文章内容包含不确定因素，请等待进一步审核");
            return false;
        }
        return false;
    }

    private void updateStatus(WmNews wmNews, int status, String reason) {
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        wmNewsDao.update(wmNews);
    }

    /*获取文章信息*/
    private Map<String, Object> extractTextAndImages(WmNews wmNews) {
        //将文本信息封装到StringBuilder
        StringBuilder text = new StringBuilder();
        //将图片信息封装到list
        List<String> images = new ArrayList<>();

        //抽取标题信息
        String title = wmNews.getTitle();
        text.append(title);
        //抽取封面图片
        if (StringUtils.isNotBlank(wmNews.getImages())) {
            String[] split = wmNews.getImages().split(",");
            images.addAll(Arrays.asList(split));
        }
        //抽取文章内容
        List<Map> maps = JSON.parseArray(wmNews.getContent(), Map.class);
        for (Map map : maps) {
            //获取内容图片
            if ("image".equals(map.get("type"))) {
                images.add(map.get("value").toString());
            }
            //获取内容文本
            if ("text".equals(map.get("type"))) {
                text.append("," + map.get("value"));
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("text", text.toString());
        result.put("images", images);

        return result;
    }
}
